import { TalentManager } from "../../Runtime/TalentManager"
import { IAttr, IWeapon, IWeaponAttr } from "../Interface/State"
import { Singleton } from "../Singleton"
import { ActorSkillTypeEnum, AttrTypeEnum } from "../common/Enum"
import { G, GMoveSpeed } from "../common/Global"
import { deepClone, toFixed } from "../common/Util"
import { ConfigManager } from "./ConfigManager"
import { GameLogic } from "./GameLogic"
import { SkillManager } from "./SkillManager"

/** 属性管理器 */
export class AttributeManager extends Singleton {

    get hpMax() {
        return this.attribute.hpMax
    }
    get defense() {
        return this.attribute.defense
    }
    get damage() {
        return this.attribute.damage
    }
    get growth() {
        return this.attribute.growth
    }
    get regeneration() {
        return this.attribute.regeneration
    }
    get knckback() {
        return this.attribute.knckback
    }
    get range() {
        return this.attribute.range
    }
    get fireRate() {
        return this.attribute.fireRate
    }
    get lootRange() {
        return this.attribute.lootRange
    }
    get critRate() {
        return this.attribute.critRate
    }
    get critChance() {
        return this.attribute.critChance
    }
    get moveSpeed() {
        return this.attribute.moveSpeed
    }
    get hpMaxRate() {
        return this.attribute.hpMaxRate
    }
    get defenseRate() {
        return this.attribute.defenseRate
    }
    get damageRate() {
        return this.attribute.damageRate
    }
    get weaponNumber() {
        return this.attribute.weaponNumber
    }
    get propNumber() {
        return this.attribute.propNumber
    }
    get startExp() {
        return this.attribute.startExp
    }

    /** 战斗中的属性汇总 */
    private attribute: IAttr = {
        hpMax: 0,
        defense: 0,
        damage: 0,
        growth: 0,
        regeneration: 0,
        knckback: 0,
        range: 0,
        fireRate: 0,
        lootRange: 0,
        critRate: 0,
        critChance: 0,
        moveSpeed: 0,
        hpMaxRate: 0,
        defenseRate: 0,
        damageRate: 0,
        weaponNumber: 0,
        propNumber: 0,
        penetrate: 0,
        startExp: 0,
        rebornNum: 0
    }

    /** 战斗中的属性汇总 */
    private weaponsAttr: { [key: string]: IWeaponAttr } = {}

    static get Ins() {
        return super.GetInstance<AttributeManager>()
    }

    /** 计算属性 */
    countAttr() {
        const fixHp = this.attribute.hpMax - GameLogic.Ins.state.actors[0].hp
        this.resetAttr()

        for (const id in GameLogic.Ins.state.props) {
            const { entityType, star } = GameLogic.Ins.state.props[id]
            const propCfg = ConfigManager.Ins.getPropCfg({ entityType, star })
            this.attribute[AttrTypeEnum[propCfg.attrType]] += Number(propCfg.attrValue)
        }

        for (const key in GameLogic.Ins.state.actors[0].attr) {
            const attrValue = GameLogic.Ins.state.actors[0].attr[key]
            this.attribute[key] += Number(attrValue)
        }

        this.countAttrBySkill()
        this.attribute.moveSpeed += GMoveSpeed[GameLogic.Ins.state.actors[0].type]
        this.attribute = TalentManager.Ins.setTalentAttribute(this.attribute)

        GameLogic.Ins.state.actors[0].hp = this.attribute.hpMax - fixHp

        this.setWeaponAttr()

    }

    /** 技能增加的属性 */
    countAttrBySkill() {
        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.tlsj]) {
            this.attribute = SkillManager.Ins.tieLianSheJi(this.attribute)
        }

        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.bldp]) {
            this.attribute = SkillManager.Ins.boLiDaPao(this.attribute)
        }

        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.syww]) {
            this.attribute = SkillManager.Ins.shenYongWuWei(this.attribute)
        }

        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.bdrs]) {
            this.attribute = SkillManager.Ins.buDongRuShan(this.attribute)
        }

        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.zzsj]) {
            this.attribute = SkillManager.Ins.zhanZhuangSheJi(this.attribute)
        }

        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.bkys]) {
            this.attribute = SkillManager.Ins.buKeYiShi(this.attribute)
        }

        if (SkillManager.Ins.actorSkill[ActorSkillTypeEnum.bzbd]) {
            this.attribute = SkillManager.Ins.baiZhanBuDai(this.attribute)
        }

    }

    /** 重置属性 */
    resetAttr() {
        this.attribute = {
            hpMax: 0,
            defense: 0,
            damage: 0,
            growth: 0,
            regeneration: 0,
            knckback: 0,
            range: 0,
            fireRate: 0,
            lootRange: 0,
            critRate: 0,
            critChance: 0,
            moveSpeed: 0,
            hpMaxRate: 0,
            defenseRate: 0,
            damageRate: 0,
            weaponNumber: 4,
            propNumber: 4,
            penetrate: 0,
            startExp: 0,
            rebornNum: 0,
        }
    }

    getDefaultWeaponAttr() {
        return {
            aimRadiu: 0,
            shootRadiu: 0,
            critChance: 0,
            critRate: 0,
            damage: 0,
            penetrate: 0,
            shootCD: 0,
        }
    }

    /** 计算玩家属性后的武器属性值 */
    setWeaponAttr() {
        for (const key in GameLogic.Ins.state.weapons) {
            const weapon = GameLogic.Ins.state.weapons[key]
            this.weaponsAttr[weapon.id] = this.getDefaultWeaponAttr()
            const weaponCfg = ConfigManager.Ins.getWeaponCfg(weapon)
            this.weaponsAttr[weapon.id].aimRadiu = weaponCfg.aimRadiu + this.attribute.range
            this.weaponsAttr[weapon.id].shootRadiu = weaponCfg.shootRadiu + this.attribute.range
            this.weaponsAttr[weapon.id].critChance = toFixed((this.attribute.critChance + weaponCfg.critChance) / 100)
            this.weaponsAttr[weapon.id].critRate = toFixed((this.attribute.critRate + weaponCfg.critRate) / 100)
            let damageRate = this.attribute.damageRate
            if (SkillManager.Ins.shengMingSheJi(weapon)) {
                damageRate += 2
            }
            let weaponDamage = (weaponCfg.damage + this.attribute.damage) * (1 + damageRate)
            if (weaponDamage <= 0) weaponDamage = 1
            this.weaponsAttr[weapon.id].damage = Math.round(weaponDamage)
            this.weaponsAttr[weapon.id].shootCD = toFixed(weaponCfg.shootCD * Math.max((100 - this.attribute.fireRate) / 100, 0.1))
            this.weaponsAttr[weapon.id].penetrate = weaponCfg.penetrate
            this.weaponsAttr[weapon.id].special = weaponCfg?.special
        }
    }

    /** 当前总属性 */
    getAttr(): IAttr {
        return deepClone(this.attribute)
    }

    /** 当前武器属性 */
    getWeaponAttr(weapon: IWeapon): IWeaponAttr {
        return deepClone(this.weaponsAttr[weapon.id])
    }

    /** 吃经验球范围 */
    getExpRange() {
        return G.EatExpRange * (1 + this.attribute.lootRange / 100)
    }

    /** 获取经验值 */
    getExpGrowth(exp = 1) {
        return exp * (1 + this.attribute.growth / 100)
    }

}